#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

#define MSG_SIZE 80
#define MAX_CLIENTS 95
#define MYPORT 7400

void exitClient(int fd, fd_set *readfds, char fd_array[], int *num_clients) {
	int i;

	close(fd);
	FD_CLR(fd, readfds);
	// czyszczenie danych klienta, ktory sie rozlacza
	for (i = 0; i < (*num_clients) - 1; i++)
		if (fd_array[i] == fd)
			break;
	for (; i < (*num_clients) - 1; i++)
		(fd_array[i]) = (fd_array[i + 1]);
	(*num_clients)--;
}

int main(int argc, char *argv[]) {
	int i = 0;

	int port;
	int num_clients = 0;
	struct sockaddr_in server_address;
	int addresslen = sizeof(struct sockaddr_in);
	int fd;
	char fd_array[MAX_CLIENTS];
	fd_set readfds, testfds, clientfds;
	char msg[MSG_SIZE + 1];
	char kb_msg[MSG_SIZE + 10];

	/*Zmienne klienta =======================*/
	int sockfd;
	int result;
	char hostname[MSG_SIZE];
	struct hostent *hostinfo;
	struct sockaddr_in address;
	char alias[MSG_SIZE] = "alias: ";
	int clientid;

	/*Klient==================================================*/
	if (argc == 2 || argc == 4) {
		if (!strcmp("-p", argv[1])) {
			if (argc == 2) {
				printf("Zle parametry.\nUzycie: client [-p PORT] adresIP\n");
				exit(0);
			} else {
				sscanf(argv[2], "%i", &port);
				strcpy(hostname, argv[3]);
			}
		} else {
			port = MYPORT;
			strcpy(hostname, argv[1]);
		}
		printf("\n*** Start klienta... (wpisz \"quit\" zeby zatrzymac): \n");
		fflush(stdout);

		/* Tworzenie socketa dla klienta */
		sockfd = socket(AF_INET, SOCK_STREAM, 0);

		/* Wypelnienie struktury sockaddr_in */
		hostinfo = gethostbyname(hostname); /* pobranie hostname */
		address.sin_addr = *(struct in_addr *) *hostinfo->h_addr_list;
		address.sin_family = AF_INET;
		address.sin_port = htons(port);

		/* Polaczenie socketu z socketem serwera */
		if (connect(sockfd, (struct sockaddr *) &address, sizeof(address))
				< 0) {
			perror("laczenie...");
			exit(1);
		}

		fflush(stdout);

		FD_ZERO(&clientfds);
		FD_SET(sockfd, &clientfds);
		FD_SET(0, &clientfds);


		/* Petla do komunikacji z serwerem */
		while (1) {
			testfds = clientfds;
			select(FD_SETSIZE, &testfds, NULL, NULL, NULL);

			for (fd = 0; fd < FD_SETSIZE; fd++) {
				if (FD_ISSET(fd,&testfds)) {
					if (fd == sockfd) { /*Akceptacja danych z otwartego socketu */
						//printf("klient - czytam \n");

						// Czytanie danych z otwartego socketu
						result = read(sockfd, msg, MSG_SIZE);
						msg[result] = '\0'; /* Zakonczenie stringa nullem */
						printf("%s", msg + 1);

						if (msg[0] == 'X') {
							close(sockfd);
							exit(0);
						}
					} else if (fd == 0) { /* Aktywnosc zwiazana z czytaniem eventow klawiatury*/
						// printf("klient - wysylam\n");

						fgets(kb_msg, MSG_SIZE + 1, stdin);

						//printf("%s\n",kb_msg);
						if (strcmp(kb_msg, "quit\n") == 0) {
							sprintf(msg, "Klient sie zamyka...\n");
							write(sockfd, msg, strlen(msg));
							close(sockfd); // zamykanie klienta
							exit(0); // koniec programu
						} else {
							/* sprintf(kb_msg,"%s",alias);
							 msg[result]='\0';
							 strcat(kb_msg,msg+1);*/

							sprintf(msg, "M%s", kb_msg);
							write(sockfd, msg, strlen(msg));
						}
					}
				}
			}
		}
	} // koniec kodu klienta

}
